package com.zlm.demo1;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author: 郑
 * 使用Lock锁实现
 * 1 创建锁
 * 2 try{}catch{}要加锁的业务代码
 * 3 finally 解锁
 * synchronized和lock区别：
 * 1 synchronized是内置的关键字，lock是一个java类
 * 2 synchronized无法判断获取锁的状态，lock可以判断是否获取到锁
 * 3 synchronized会自动释放锁，lock必须要手动释放锁，死锁
 * 4 synchronized线程1（获得锁，阻塞），线程2（必须等待），lock锁不一定会等待下去
 * 5 synchronized可重入锁，不可以中断，非公平，lock可重入锁，可以通过判断锁中断，非公平（默认，可以配置）
 * 6 synchronized适合锁少量代码同步问题，lock适合锁大量的同步代码
 */
public class SaleTicketDemo3 {
    public static void main(String[] args) {
        Ticket3 ticket3 = new Ticket3();
        new Thread(()->{
            for (int i = 0; i < 50; i++) {
                ticket3.sale();
            }
        },"a").start();
        new Thread(()->{
            for (int i = 0; i < 50; i++) {
                ticket3.sale();
            }
        },"B").start();
    }
}

class Ticket3{
    // 属性方法
    private int num = 50;
    //创建可重入锁
    Lock lock = new ReentrantLock();
    //买票

    public void sale(){
        //加锁
        lock.lock();

        try {
            if(num > 0){
                System.out.println(Thread.currentThread().getName()+"卖出了"+(51 - num--)+"张票，还有"+num+"张票");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //解锁
            lock.unlock();
        }
    }
}

